package com.sky.service.impl;

import com.sky.dto.GoodsSalesDTO;
import com.sky.entity.Orders;
import com.sky.mapper.OrderMapper;
import com.sky.mapper.UserMapper;
import com.sky.result.PageResult;
import com.sky.service.ReportService;
import com.sky.service.WorkspaceService;
import com.sky.vo.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.apache.poi.util.StringUtil;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.*;

@Slf4j
@Service
public class ReportServiceImpl implements ReportService {
    @Autowired
    OrderMapper orderMapper;
    @Autowired
    UserMapper userMapper;
    @Autowired
    WorkspaceService workspaceService;

    @Override
    public TurnoverReportVO turnoverStatistics(LocalDate begin, LocalDate end) {
        //查询时间列表
        ArrayList<LocalDate> timeList = new ArrayList<>();
        timeList.add(begin);
        while (!begin.equals(end)) {
            begin = begin.plusDays(1);
            timeList.add(begin);
        }
        log.info("营业额统计时间:{}", timeList);
        //查询时间列表对应的营业额
        //遍历时间列表 查询每一天的营业额数据
        ArrayList<BigDecimal> turnoverList = new ArrayList<>();
        for (LocalDate localDate : timeList) {
            BigDecimal bigDecimal = orderMapper.sumByCondittion(Orders.COMPLETED, localDate);
            turnoverList.add(bigDecimal);
        }
        //封装vo返回
        TurnoverReportVO turnoverReportVO = new TurnoverReportVO();
        turnoverReportVO.setTurnoverList(StringUtils.join(turnoverList, ","));
        turnoverReportVO.setDateList(StringUtils.join(timeList, ","));
        return turnoverReportVO;
    }

    @Override
    public UserReportVO userStatistics(LocalDate begin, LocalDate end) {
        //获取时间列表
        LocalDate beforeData = begin.minusDays(1);
        //查询时间列表
        ArrayList<LocalDate> timeList = new ArrayList<>();
        timeList.add(begin);
        while (!begin.equals(end)) {
            begin = begin.plusDays(1);
            timeList.add(begin);
        }
        log.info("用户统计的时间列表:{}", timeList);
        //遍历时间区间列表 统计每一天的新增用户 每天的用户总量
        ArrayList<Integer> newUserList = new ArrayList<>();
        ArrayList<Integer> allUserList = new ArrayList<>();
        Map param = new HashMap();
        param.put("allUser", beforeData);
        Integer allUserCount = userMapper.countByMap(param);
        for (LocalDate localDate : timeList) {
            param.put("allUser", null);
            param.put("newUser", localDate);
            Integer newUserCount = userMapper.countByMap(param);
            newUserList.add(newUserCount);
            allUserCount += newUserCount;
            allUserList.add(allUserCount);
        }
        //封装查询结果到每日新增用户集合和每天用户总量集合中
        UserReportVO userReportVO = new UserReportVO();
        userReportVO.setDateList(StringUtils.join(timeList, ","));
        userReportVO.setNewUserList(StringUtils.join(newUserList, ","));
        userReportVO.setTotalUserList(StringUtils.join(allUserList, ","));

        //封装vo返回结果
        return userReportVO;
    }

    @Override
    public OrderReportVO ordersStatistics(LocalDate begin, LocalDate end) {
        //获取时间列表
        ArrayList<LocalDate> timeList = new ArrayList<>();
        timeList.add(begin);
        while (!begin.equals(end)) {
            begin = begin.plusDays(1);
            timeList.add(begin);
        }
        log.info("订单统计的时间列表:{}", timeList);
        //申明时间区间内的订单总量/有效的订单量/订单完成率
        Double orderCompletionRate = 0.00;
        Integer totalOrderCount = 0;
        Integer validOrderCount = 0;
        //遍历时间列表
        //循环时间列表 统计每一天的订单总量/有效的订单量
        ArrayList<Integer> totalOrderCountList = new ArrayList<>();
        ArrayList<Integer> validOrderCountList = new ArrayList<>();
        for (LocalDate localDate : timeList) {
            Map param = new HashMap();
            param.put("date", localDate);
            Integer totalOrder = orderMapper.coutByMap(param);

            param.put("status", Orders.COMPLETED);
            Integer validOrder = orderMapper.coutByMap(param);

            totalOrderCountList.add(totalOrder);
            validOrderCountList.add(validOrder);

            //累加每一天的订单量
            totalOrderCount += totalOrder;
            validOrderCount += validOrder;
        }
        //计算时间区间内的订单总量/有效的订单量/订单完成率
        orderCompletionRate = validOrderCount.doubleValue() / totalOrderCount;


        //封装vo返回结果
        OrderReportVO orderReportVO = new OrderReportVO();
        orderReportVO.setDateList(StringUtils.join(timeList, ","));//时间列表
        orderReportVO.setOrderCountList(StringUtils.join(totalOrderCountList, ","));//订单总量
        orderReportVO.setValidOrderCountList(StringUtils.join(validOrderCountList, ","));//有效订单量
        orderReportVO.setValidOrderCount(validOrderCount);//时间范围内的订单量
        orderReportVO.setTotalOrderCount(totalOrderCount);//时间范围内的订单总量
        orderReportVO.setOrderCompletionRate(orderCompletionRate);//订单完成率
        return orderReportVO;
    }

    @Override
    public SalesTop10ReportVO top10(LocalDate begin, LocalDate end) {
        //调用持久层 查询订单表
        List<GoodsSalesDTO>  goodsSalesDTOS = orderMapper.selectTop10(begin, end);
        //处理查询结果
        List<String> nameList = new ArrayList<>();
        List<Integer> nunberList = new ArrayList<>();
        for (GoodsSalesDTO goodsSalesDTO : goodsSalesDTOS) {
            nameList.add(goodsSalesDTO.getName());
            nunberList.add(goodsSalesDTO.getNumber());
        }

        //封装ov返回
        SalesTop10ReportVO salesTop10ReportVO = new SalesTop10ReportVO();
        salesTop10ReportVO.setNameList(StringUtils.join(nameList, ","));//菜品top10名称列表
        salesTop10ReportVO.setNumberList(StringUtils.join(nunberList, ","));//菜品top10销量列表
        return salesTop10ReportVO;
    }

    @Override
    public void exportExcel(HttpServletResponse response) throws IOException {
        InputStream is = this.getClass().getClassLoader().getResourceAsStream("运营数据报表模板.xlsx");
        //创建excel对象
        XSSFWorkbook excel = new XSSFWorkbook(is);
        //创建sheet页对象
        XSSFSheet sheet = excel.getSheet("Sheet1");
        //创建row行对象
        //创建cell列对象
        //获取单元格写入指定数据

        LocalDate now = LocalDate.now();
        LocalDate Date = now.minusDays(30);
        Double turnover = 0.00;
        Integer newUsers = 0;
        Integer validOrderCount = 0;
        for (int i = 0; i < 30; i++) {
            BusinessDataVO businessDataVO = workspaceService.businessData(Date);
            sheet.getRow(7 + i).getCell(1).setCellValue(Date.toString());
            sheet.getRow(7 + i).getCell(2).setCellValue(businessDataVO.getTurnover().toString());
            sheet.getRow(7 + i).getCell(3).setCellValue(businessDataVO.getValidOrderCount());
            sheet.getRow(7 + i).getCell(4).setCellValue(businessDataVO.getOrderCompletionRate());
            sheet.getRow(7 + i).getCell(5).setCellValue(businessDataVO.getUnitPrice());
            sheet.getRow(7 + i).getCell(6).setCellValue(businessDataVO.getNewUsers());
            Date = Date.plusDays(1);
           turnover += businessDataVO.getTurnover();//累加营业额
          validOrderCount += businessDataVO.getValidOrderCount();//累加月有效订单
          newUsers += businessDataVO.getNewUsers();//累加月新增用户
        }
        Map param = new HashMap();
        param.put("begin",LocalDate.now().minusDays(30));
        param.put("end",LocalDate.now().minusDays(1));
        Integer totalOrderCount = orderMapper.coutByMap(param);
        sheet.getRow(3).getCell(2).setCellValue(turnover);//近一个月的营业额
        sheet.getRow(3).getCell(4).setCellValue(validOrderCount.doubleValue()/totalOrderCount);//订单完成率
        sheet.getRow(3).getCell(6).setCellValue(newUsers);//进一个月新增的用户数据
        sheet.getRow(4).getCell(2).setCellValue(validOrderCount);//近一个月的有效订单
        sheet.getRow(4).getCell(4).setCellValue(turnover.doubleValue()/validOrderCount);//近一个月的平均单价



        //将excel表格对象 输出到指定盘符

        excel.write(response.getOutputStream());
        excel.close();
        System.out.println("写入成功");
    }
}
